package liquibase.ext.spatial.datatype; import liquibase.database.Database; import liquibase.database.core.DerbyDatabase; import liquibase.database.core.H2Database; import liquibase.database.core.OracleDatabase; import liquibase.database.core.PostgresDatabase; import liquibase.datatype.DataTypeInfo; import liquibase.datatype.DatabaseDataType; import liquibase.datatype.LiquibaseDataType; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.statement.DatabaseFunction; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; /** * The <code>GeometryType</code> assists in defining database-specific geometry types and converting * SQL representations of geometries. */ @DataTypeInfo(name = "geometry", aliases = { "com.vividsolutions.jts.geom.Geometry" }, minParameters = 0, maxParameters = 2, priority = LiquibaseDataType.PRIORITY_DEFAULT) public class GeometryType extends LiquibaseDataType { /** * Returns the value geometry type parameter. * * @return the geometry type or <code>null</code> if not present. */ public String getGeometryType() { String geometryType = null; if (getParameters().length > 0 && getParameters()[0] != null) { geometryType = getParameters()[0].toString(); } return geometryType; } /** * Returns the value SRID parameter. * * @return the SRID or <code>null</code> if not present. */ public Integer getSRID() { Integer srid = null; if (getParameters().length > 1 && getParameters()[1] != null) { srid = Integer.valueOf(getParameters()[1].toString()); } return srid; } /** * Creates the appropriate Geometry <code>DatabaseDataType</code>. */ @Override public DatabaseDataType toDatabaseDataType(final Database database) { final DatabaseDataType databaseDataType; if (database instanceof DerbyDatabase) { databaseDataType = new DatabaseDataType("VARCHAR(32672) FOR BIT DATA"); } else if (database instanceof H2Database) { // User's wanting to use a BLOB can use modifySql. databaseDataType = new DatabaseDataType("BINARY"); } else if (database instanceof OracleDatabase) { databaseDataType = new DatabaseDataType("SDO_GEOMETRY"); } else if (database instanceof PostgresDatabase) { databaseDataType = new DatabaseDataType(getName(), getParameters()); } else { databaseDataType = new DatabaseDataType("GEOMETRY"); } return databaseDataType; } /** * @see liquibase.datatype.LiquibaseDataType#objectToSql(java.lang.Object, * liquibase.database.Database) */ @Override public String objectToSql(final Object value, final Database database) { final String returnValue; if (value instanceof Geometry) { // TODO: Tailor the output for the database. returnValue = ((Geometry) value).toText(); } else if (value instanceof String) { returnValue = value.toString(); } else if (value instanceof DatabaseFunction) { returnValue = value.toString(); } else if (value == null || value.toString().equalsIgnoreCase("null")) { returnValue = null; } else { throw new UnexpectedLiquibaseException("Cannot convert type " + value.getClass() + " to a Geometry value"); } return returnValue; } /** * @see liquibase.datatype.LiquibaseDataType#sqlToObject(java.lang.String, * liquibase.database.Database) */ @Override public Object sqlToObject(final String value, final Database database) { final Geometry returnValue; if (value == null || value.equalsIgnoreCase("null")) { returnValue = null; } else { final WKTReader reader = new WKTReader(); try { // TODO: Check for SRID. returnValue = reader.read(value); } catch (final ParseException e) { throw new UnexpectedLiquibaseException("Cannot parse " + value + " to a Geometry", e); } } return returnValue; } }